import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'dart:typed_data';
import 'package:crypto/crypto.dart';
import 'package:dio/dio.dart';
import 'package:get/get.dart';
import 'package:xml/xml.dart';
import 'package:intl/intl.dart';

import '../models/tianyi_user.dart';
import '../models/file_metadata.dart';
import 'database_service.dart';

class TianyiCloudService extends GetxService {
  // TV应用API常量
  static const String tvAppKey = '600100885';
  static const String tvAppSignatureSecret = 'fe5734c74c2f96a38157f420b32dc995';
  static const String tvVersion = '6.5.5';
  static const String androidTv = 'FAMILY_TV';
  static const String tvChannelId = 'home02';
  
  static const String _baseUrl = 'https://cloud.189.cn';
  static const String _apiUrl = 'https://api.cloud.189.cn';
  
  late Dio _dio;
  final DatabaseService _databaseService = Get.find<DatabaseService>();
  
  TianyiUser? _currentUser;
  TianyiUser? get currentUser => _currentUser;
  
  final RxBool _isLoggedIn = false.obs;
  bool get isLoggedIn => _isLoggedIn.value;
  
  // Token信息存储
  Map<String, dynamic> tokenInfo = {};
  String? familyId;
  
  @override
  Future<void> onInit() async {
    super.onInit();
    _initDio();
    await _loadCurrentUser();
  }
  
  void _initDio() {
    _dio = Dio(BaseOptions(
      connectTimeout: const Duration(seconds: 30),
      receiveTimeout: const Duration(seconds: 30),
      headers: {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
        'Accept': 'application/json, text/plain, */*',
        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
      },
    ));
    
    // 添加拦截器
    _dio.interceptors.add(InterceptorsWrapper(
      onRequest: (options, handler) {
        // 添加认证头
        if (_currentUser?.sessionKey != null) {
          options.headers['SessionKey'] = _currentUser!.sessionKey;
        }
        handler.next(options);
      },
      onError: (error, handler) {
        if (error.response?.statusCode == 401) {
          // 会话过期，清除登录状态
          _logout();
        }
        handler.next(error);
      },
    ));
  }
  
  Future<void> _loadCurrentUser() async {
    _currentUser = await _databaseService.getCurrentTianyiUser();
    if (_currentUser != null && _currentUser!.isSessionValid) {
      _isLoggedIn.value = true;
    } else {
      _isLoggedIn.value = false;
      _currentUser = null;
    }
  }
  
  // 客户端参数后缀
  Map<String, String> clientSuffix() {
    return {
      'clientType': androidTv,
      'version': tvVersion,
      'channelId': tvChannelId,
    };
  }
  
  // 获取HTTP日期字符串
  String getHttpDateStr() {
    final now = DateTime.now().toUtc();
    final formatter = DateFormat('EEE, dd MMM yyyy HH:mm:ss', 'en_US');
    return '${formatter.format(now)} GMT';
  }
  
  // 获取时间戳
  int timestamp() {
    return DateTime.now().millisecondsSinceEpoch;
  }
  
  // SessionKey HMAC签名
  String sessionKeySignatureOfHmac(String sessionSecret, String sessionKey, String operate, String fullUrl, String dateOfGmt) {
    final urlPattern = RegExp(r'://[^/]+((/[^/\s?#]+)*)');
    final match = urlPattern.firstMatch(fullUrl);
    final urlPath = match?.group(1) ?? '';
    
    final data = 'SessionKey=$sessionKey&Operate=$operate&RequestURI=$urlPath&Date=$dateOfGmt';
    final key = utf8.encode(sessionSecret);
    final bytes = utf8.encode(data);
    final hmacSha1 = Hmac(sha1, key);
    final digest = hmacSha1.convert(bytes);
    
    return digest.toString().toUpperCase();
  }
  
  // AppKey HMAC签名
  String appKeySignatureOfHmac(String sessionSecret, String appKey, String operate, String fullUrl, int timestamp) {
    final urlPattern = RegExp(r'://[^/]+((/[^/\s?#]+)*)');
    final match = urlPattern.firstMatch(fullUrl);
    final urlPath = match?.group(1) ?? '';
    
    final data = 'AppKey=$appKey&Operate=$operate&RequestURI=$urlPath&Timestamp=$timestamp';
    final key = utf8.encode(sessionSecret);
    final bytes = utf8.encode(data);
    final hmacSha1 = Hmac(sha1, key);
    final digest = hmacSha1.convert(bytes);
    
    return digest.toString().toUpperCase();
  }
  
  // 生成签名头
  Map<String, String> signatureHeader(String url, String method, {bool isFamily = false}) {
    final dateOfGmt = getHttpDateStr();
    String sessionKey = tokenInfo['sessionKey'] ?? '';
    String sessionSecret = tokenInfo['sessionSecret'] ?? '';
    
    if (isFamily) {
      sessionKey = tokenInfo['familySessionKey'] ?? '';
      sessionSecret = tokenInfo['familySessionSecret'] ?? '';
    }
    
    return {
      'Date': dateOfGmt,
      'SessionKey': sessionKey,
      'X-Request-ID': _generateUuid(),
      'Signature': sessionKeySignatureOfHmac(sessionSecret, sessionKey, method, url, dateOfGmt),
    };
  }
  
  // 生成AppKey签名头
  Map<String, String> appKeySignatureHeader(String url, String method) {
    final tempTime = timestamp();
    return {
      'Timestamp': tempTime.toString(),
      'X-Request-ID': _generateUuid(),
      'AppKey': tvAppKey,
      'AppSignature': appKeySignatureOfHmac(tvAppSignatureSecret, tvAppKey, method, url, tempTime),
    };
  }
  
  // 生成UUID
  String _generateUuid() {
    final random = Random();
    final bytes = List<int>.generate(16, (i) => random.nextInt(256));
    bytes[6] = (bytes[6] & 0x0f) | 0x40; // Version 4
    bytes[8] = (bytes[8] & 0x3f) | 0x80; // Variant bits
    
    final hex = bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join();
    return '${hex.substring(0, 8)}-${hex.substring(8, 12)}-${hex.substring(12, 16)}-${hex.substring(16, 20)}-${hex.substring(20, 32)}';
  }
  
  // 获取二维码UUID
  Future<String?> getQrUuid() async {
    try {
      final url = '$_apiUrl/family/manage/getQrCodeUUID.action';
      final headers = appKeySignatureHeader(url, 'GET');
      final params = clientSuffix();
      
      final response = await _dio.get(
        url,
        queryParameters: params,
        options: Options(headers: headers),
      );
      
      print('QR UUID Response Status: ${response.statusCode}');
      print('QR UUID Response Text: ${response.data}');
      
      if (response.statusCode == 200) {
        try {
          // 尝试解析XML
          final document = XmlDocument.parse(response.data.toString());
          final uuidElement = document.findAllElements('uuid').first;
          return uuidElement.text;
        } catch (e) {
          print('XML parse error: $e');
          // 如果XML解析失败，尝试JSON
          try {
            final data = response.data;
            if (data is Map && data.containsKey('uuid')) {
              return data['uuid'];
            }
          } catch (jsonE) {
            print('JSON decode error: $jsonE');
          }
        }
      }
      return null;
    } catch (e) {
      print('获取二维码UUID失败: $e');
      return null;
    }
  }
  
  // 获取登录二维码
  Future<Map<String, dynamic>> getLoginQrCode() async {
    try {
      final uuid = await getQrUuid();
      if (uuid == null) {
        throw Exception('获取二维码UUID失败');
      }
      
      // 生成二维码URL
      final qrCodeUrl = 'https://open.e.189.cn/api/logbox/oauth2/qrcode.do?appId=$tvAppKey&redirectUri=https://cloud.189.cn/api/portal/loginUrl.action&uuid=$uuid';
      
      return {
        'qrCodeUrl': qrCodeUrl,
        'qrId': uuid,
      };
    } catch (e) {
      throw Exception('获取二维码失败: $e');
    }
  }
  
  // 检查二维码登录状态
  Future<String?> checkQrLogin(String uuid) async {
    try {
      final url = '$_apiUrl/family/manage/qrcodeLoginResult.action';
      final headers = appKeySignatureHeader(url, 'GET');
      final params = {
        'uuid': uuid,
        ...clientSuffix(),
      };
      
      final response = await _dio.get(
        url,
        queryParameters: params,
        options: Options(headers: headers),
      );
      
      print('QR Login Check Response Status: ${response.statusCode}');
      print('QR Login Check Response Text: ${response.data}');
      
      if (response.statusCode == 200) {
        try {
          // 尝试解析XML
          final document = XmlDocument.parse(response.data.toString());
          final accessTokenElement = document.findAllElements('accessToken').firstOrNull;
          if (accessTokenElement != null) {
            return accessTokenElement.text;
          }
        } catch (e) {
          print('XML parse error: $e');
          // 如果XML解析失败，尝试JSON
          try {
            final data = response.data;
            if (data is Map && data.containsKey('accessToken')) {
              return data['accessToken'];
            }
          } catch (jsonE) {
            print('JSON decode error: $jsonE');
          }
        }
      }
      return null;
    } catch (e) {
      print('检查二维码登录失败: $e');
      return null;
    }
  }
  
  // 检查二维码登录状态（兼容旧接口）
  Future<Map<String, dynamic>> checkQrCodeStatus(String qrId) async {
    try {
      final accessToken = await checkQrLogin(qrId);
      if (accessToken != null) {
        return {
          'status': 2, // 已确认
          'message': '登录成功',
          'accessToken': accessToken,
        };
      } else {
        return {
          'status': 0, // 待扫描
          'message': '等待扫描',
        };
      }
    } catch (e) {
      return {
        'status': 3, // 已取消/错误
        'message': '登录失败: $e',
      };
    }
  }
  
  // Token登录
  Future<bool> loginWithToken(String accessToken) async {
    try {
      final url = '$_apiUrl/family/manage/getFamilyList.action';
      final headers = appKeySignatureHeader(url, 'GET');
      final params = {
        'accessToken': accessToken,
        ...clientSuffix(),
      };
      
      final response = await _dio.get(
        url,
        queryParameters: params,
        options: Options(headers: headers),
      );
      
      print('Token Login Response Status: ${response.statusCode}');
      print('Token Login Response Text: ${response.data}');
      
      if (response.statusCode == 200) {
        try {
          // 尝试解析XML
          final document = XmlDocument.parse(response.data.toString());
          
          // 提取token信息
          final sessionKeyElement = document.findAllElements('sessionKey').firstOrNull;
          final sessionSecretElement = document.findAllElements('sessionSecret').firstOrNull;
          final familySessionKeyElement = document.findAllElements('familySessionKey').firstOrNull;
          final familySessionSecretElement = document.findAllElements('familySessionSecret').firstOrNull;
          
          if (sessionKeyElement != null && sessionSecretElement != null) {
            tokenInfo = {
              'sessionKey': sessionKeyElement.text,
              'sessionSecret': sessionSecretElement.text,
              'familySessionKey': familySessionKeyElement?.text ?? '',
              'familySessionSecret': familySessionSecretElement?.text ?? '',
            };
            
            // 获取家庭ID
            final familyElement = document.findAllElements('family').firstOrNull;
            if (familyElement != null) {
              final familyIdElement = familyElement.findElements('familyId').firstOrNull;
              if (familyIdElement != null) {
                familyId = familyIdElement.text;
              }
            }
            
            // 创建用户对象
            _currentUser = TianyiUser(
              userId: 'user_${DateTime.now().millisecondsSinceEpoch}',
              nickname: '天翼用户',
              avatar: '',
              phone: '',
              email: '',
              totalSpace: 0,
              usedSpace: 0,
              sessionKey: tokenInfo['sessionKey']!,
              sessionSecret: tokenInfo['sessionSecret']!,
              loginTime: DateTime.now(),
              expireTime: DateTime.now().add(const Duration(days: 30)),
              isLoggedIn: true,
            );
            
            // 保存到数据库
            await _databaseService.insertOrUpdateTianyiUser(_currentUser!);
            _isLoggedIn.value = true;
            
            return true;
          }
        } catch (e) {
          print('XML parse error: $e');
        }
      }
      
      return false;
    } catch (e) {
      print('Token登录失败: $e');
      return false;
    }
  }
  
  // 完成登录（兼容旧接口）
  Future<bool> completeLogin(String accessTokenOrRedirectUrl) async {
    try {
      // 检查是否是accessToken还是redirectUrl
      if (accessTokenOrRedirectUrl.startsWith('http')) {
        // 是redirectUrl，从中提取accessToken
        final uri = Uri.parse(accessTokenOrRedirectUrl);
        final accessToken = uri.queryParameters['accessToken'];
        if (accessToken != null) {
          return await loginWithToken(accessToken);
        }
      } else {
        // 直接是accessToken
        return await loginWithToken(accessTokenOrRedirectUrl);
      }
      
      throw Exception('无效的登录信息');
    } catch (e) {
      throw Exception('登录失败: $e');
    }
  }
  
  // 获取文件信息
  Future<Map<String, dynamic>?> getFileInfo(String fileId, {bool isFamily = false}) async {
    if (!isLoggedIn) throw Exception('未登录');
    
    // 通过递归搜索获取文件信息
    final fileList = await getFileList('-11', isFamily: isFamily);
    if (fileList != null) {
      // 在文件列表中查找指定文件
      final files = fileList['files'] as List<Map<String, dynamic>>;
      for (final file in files) {
        if (file['id'] == fileId) {
          return file;
        }
      }
    }
    
    return null;
  }
  
  // 登出
  Future<void> logout() async {
    await _logout();
  }
  
  Future<void> _logout() async {
    await _databaseService.logoutTianyiUser();
    _currentUser = null;
    _isLoggedIn.value = false;
  }
  
  // 获取文件列表
  Future<Map<String, dynamic>?> getFileList(String folderId, {bool isFamily = false}) async {
    if (!isLoggedIn) throw Exception('未登录');
    
    String url;
    Map<String, String> params;
    
    if (isFamily) {
      url = '$_apiUrl/family/file/getFamilyFileList.action';
      params = {
        'familyId': familyId ?? '',
        'folderId': folderId,
        'mediaType': '0',
        'iconOption': '5',
        'orderBy': '1',
        'descending': 'true',
        'pageNum': '1',
        'pageSize': '100',
        ...clientSuffix(),
      };
    } else {
      url = '$_apiUrl/listFiles.action';
      params = {
        'folderId': folderId,
        'mediaType': '0',
        'iconOption': '5',
        'orderBy': '1',
        'descending': 'true',
        'pageNum': '1',
        'pageSize': '100',
        ...clientSuffix(),
      };
    }
    
    final headers = signatureHeader(url, 'GET', isFamily: isFamily);
    
    final response = await _dio.get(
      url,
      queryParameters: params,
      options: Options(headers: headers),
    );
    
    print('File List Response Status: ${response.statusCode}');
    print('File List Response Text: ${response.data}');
    
    if (response.statusCode == 200) {
      try {
        // 尝试解析XML
        final document = XmlDocument.parse(response.data.toString());
        
        final result = <String, dynamic>{
          'files': <Map<String, dynamic>>[],
          'folders': <Map<String, dynamic>>[],
        };
        
        // 解析文件夹
        for (final folder in document.findAllElements('folder')) {
          final folderInfo = <String, dynamic>{
            'id': folder.findElements('id').firstOrNull?.text ?? '',
            'parentId': folder.findElements('parentId').firstOrNull?.text ?? '',
            'name': folder.findElements('name').firstOrNull?.text ?? '',
            'createDate': folder.findElements('createDate').firstOrNull?.text ?? '',
            'lastOpTime': folder.findElements('lastOpTime').firstOrNull?.text ?? '',
            'fileCount': int.tryParse(folder.findElements('fileCount').firstOrNull?.text ?? '0') ?? 0,
            'isFolder': true,
          };
          result['folders'].add(folderInfo);
        }
        
        // 解析文件
        for (final file in document.findAllElements('file')) {
          final fileInfo = <String, dynamic>{
            'id': file.findElements('id').firstOrNull?.text ?? '',
            'parentId': file.findElements('parentId').firstOrNull?.text ?? '',
            'name': file.findElements('name').firstOrNull?.text ?? '',
            'size': int.tryParse(file.findElements('size').firstOrNull?.text ?? '0') ?? 0,
            'createDate': file.findElements('createDate').firstOrNull?.text ?? '',
            'lastOpTime': file.findElements('lastOpTime').firstOrNull?.text ?? '',
            'md5': file.findElements('md5').firstOrNull?.text ?? '',
            'mediaType': file.findElements('mediaType').firstOrNull?.text ?? '',
            'isFolder': false,
          };
          
          // 尝试获取图标信息
          final iconNode = file.findElements('icon').firstOrNull;
          if (iconNode != null) {
            fileInfo['icon'] = {
              'smallUrl': iconNode.findElements('smallUrl').firstOrNull?.text ?? '',
              'largeUrl': iconNode.findElements('largeUrl').firstOrNull?.text ?? '',
            };
          }
          
          result['files'].add(fileInfo);
        }
        
        return result;
      } catch (e) {
        print('XML parse error: $e');
      }
    }
    
    return null;
  }
  
  // 创建文件夹
  Future<String> createFolder(String parentFolderId, String folderName) async {
    if (!isLoggedIn) throw Exception('未登录');
    
    final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
    final params = {
      'method': 'createFolder',
      'parentFolderId': parentFolderId,
      'folderName': folderName,
      'timestamp': timestamp,
      'sessionKey': _currentUser!.sessionKey!,
    };
    
    final signature = _generateSignature('POST', '/api/open/file/createFolder.action', params, _currentUser!.sessionSecret!);
    params['signature'] = signature;
    
    final response = await _dio.post(
      '$_apiUrl/api/open/file/createFolder.action',
      data: params,
    );
    
    if (response.statusCode == 200 && response.data['code'] == 0) {
      return response.data['data']['folderId'];
    }
    
    throw Exception('创建文件夹失败: ${response.data['message']}');
  }
  
  // 检查文件是否存在（秒传）
  Future<Map<String, dynamic>?> checkFileExists(String md5, int fileSize) async {
    if (!isLoggedIn) throw Exception('未登录');
    
    final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
    final params = {
      'method': 'checkFileExists',
      'md5': md5,
      'size': fileSize.toString(),
      'timestamp': timestamp,
      'sessionKey': _currentUser!.sessionKey!,
    };
    
    final signature = _generateSignature('GET', '/api/open/file/checkFileExists.action', params, _currentUser!.sessionSecret!);
    params['signature'] = signature;
    
    final response = await _dio.get(
      '$_apiUrl/api/open/file/checkFileExists.action',
      queryParameters: params,
    );
    
    if (response.statusCode == 200 && response.data['code'] == 0) {
      final exists = response.data['data']['exists'];
      if (exists) {
        return response.data['data'];
      }
    }
    
    return null;
  }
  
  // 创建上传会话
  Future<Map<String, dynamic>?> createUploadSession(
    String parentId,
    String fileMd5,
    String fileName,
    int fileSize, {
    bool isFamily = false,
  }) async {
    if (!isLoggedIn) throw Exception('未登录');
    
    String url;
    Map<String, String> params;
    
    if (isFamily) {
      // 家庭云使用查询参数
      url = '$_apiUrl/family/file/createFamilyFile.action';
      params = {
        'familyId': familyId ?? '',
        'parentId': parentId,
        'fileMd5': fileMd5,
        'fileName': fileName,
        'fileSize': fileSize.toString(),
        'resumePolicy': '1',
        ...clientSuffix(),
      };
    } else {
      // 个人云使用表单数据
      url = '$_apiUrl/createUploadFile.action';
      params = {
        'parentFolderId': parentId,
        'fileName': fileName,
        'size': fileSize.toString(),
        'md5': fileMd5,
        'opertype': '3',
        'flag': '1',
        'resumePolicy': '1',
        'isLog': '0',
        ...clientSuffix(),
      };
    }
    
    final headers = signatureHeader(url, 'POST', isFamily: isFamily);
    
    final response = await _dio.post(
      url,
      data: isFamily ? null : params,
      queryParameters: isFamily ? params : null,
      options: Options(headers: headers),
    );
    
    print('Create Upload Session Response Status: ${response.statusCode}');
    print('Create Upload Session Response Text: ${response.data}');
    
    if (response.statusCode == 200) {
      try {
        // 尝试解析XML
        final document = XmlDocument.parse(response.data.toString());
        
        final result = <String, dynamic>{};
        for (final child in document.rootElement.children) {
          if (child is XmlElement) {
            switch (child.name.local) {
              case 'uploadFileId':
                result['uploadFileId'] = child.text;
                break;
              case 'fileUploadUrl':
                result['fileUploadUrl'] = child.text;
                break;
              case 'fileCommitUrl':
                result['fileCommitUrl'] = child.text;
                break;
              case 'fileDataExists':
                result['fileDataExists'] = int.tryParse(child.text) ?? 0;
                break;
            }
          }
        }
        
        print('XML parsed result: $result');
        return result;
      } catch (e) {
        print('XML decode error: $e');
      }
    }
    
    return null;
  }
  
  // 获取上传URL（兼容旧接口）
  Future<Map<String, dynamic>> getUploadUrl(String fileName, String md5, int fileSize, String parentFolderId) async {
    final result = await createUploadSession(parentFolderId, md5, fileName, fileSize);
    if (result != null) {
      return result;
    }
    throw Exception('获取上传URL失败');
  }
  
  // 上传文件数据
  Future<bool> uploadFileData(
    Map<String, dynamic> uploadInfo,
    Uint8List fileContent, {
    bool isFamily = false,
    Function(int, int)? onProgress,
  }) async {
    final uploadUrl = uploadInfo['fileUploadUrl'];
    if (uploadUrl == null) {
      return false;
    }
    
    final formData = FormData.fromMap({
      'file': MultipartFile.fromBytes(
        fileContent,
        filename: 'file',
      ),
    });
    
    try {
      final response = await _dio.post(
        uploadUrl,
        data: formData,
        onSendProgress: onProgress,
      );
      
      print('Upload File Data Response Status: ${response.statusCode}');
      return response.statusCode == 200;
    } catch (e) {
      print('上传文件数据失败: $e');
      return false;
    }
  }
  
  // 提交上传
  Future<Map<String, dynamic>?> commitUpload(
    String commitUrl,
    String uploadFileId, {
    bool isFamily = false,
    bool isRapid = false,
    bool overwrite = false,
  }) async {
    final params = <String, String>{
      'uploadFileId': uploadFileId,
      'isRapid': isRapid ? '1' : '0',
      'overwrite': overwrite ? '1' : '0',
      ...clientSuffix(),
    };
    
    try {
      final response = await _dio.post(
        commitUrl,
        data: params,
      );
      
      print('Commit Upload Response Status: ${response.statusCode}');
      print('Commit Upload Response Text: ${response.data}');
      
      if (response.statusCode == 200) {
        try {
          // 尝试解析XML
          final document = XmlDocument.parse(response.data.toString());
          
          final result = <String, dynamic>{};
          for (final child in document.rootElement.children) {
            if (child is XmlElement) {
              result[child.name.local] = child.text;
            }
          }
          
          return result;
        } catch (e) {
          print('XML decode error: $e');
        }
      }
      
      return null;
    } catch (e) {
      print('提交上传失败: $e');
      return null;
    }
  }
  
  // 上传文件（兼容旧接口）
  Future<void> uploadFile(
    String uploadUrl,
    File file,
    Map<String, dynamic> uploadParams,
    {Function(int, int)? onProgress}
  ) async {
    final fileContent = await file.readAsBytes();
    final uploadInfo = {'fileUploadUrl': uploadUrl};
    
    final success = await uploadFileData(
      uploadInfo,
      fileContent,
      onProgress: onProgress,
    );
    
    if (!success) {
      throw Exception('文件上传失败');
    }
  }
  
  // 获取下载URL
  Future<String?> getDownloadUrl(String fileId, {bool isFamily = false}) async {
    if (!isLoggedIn) throw Exception('未登录');
    
    String url;
    Map<String, String> params;
    
    if (isFamily) {
      url = '$_apiUrl/family/file/getFamilyFileDownloadUrl.action';
      params = {
        'familyId': familyId ?? '',
        'fileId': fileId,
        'dt': '3',
        ...clientSuffix(),
      };
    } else {
      url = '$_apiUrl/downloadFile.action';
      params = {
        'fileId': fileId,
        'dt': '3',
        ...clientSuffix(),
      };
    }
    
    final headers = signatureHeader(url, 'GET', isFamily: isFamily);
    
    final response = await _dio.get(
      url,
      queryParameters: params,
      options: Options(headers: headers),
    );
    
    print('Download URL Response Status: ${response.statusCode}');
    print('Download URL Response Text: ${response.data}');
    
    if (response.statusCode == 200) {
      try {
        // 尝试解析XML
        final document = XmlDocument.parse(response.data.toString());
        final downloadUrlElement = document.findAllElements('downloadUrl').firstOrNull;
        if (downloadUrlElement != null) {
          return downloadUrlElement.text;
        }
      } catch (e) {
        print('XML parse error: $e');
        // 如果XML解析失败，尝试JSON
        try {
          final data = response.data;
          if (data is Map && data.containsKey('downloadUrl')) {
            return data['downloadUrl'];
          }
        } catch (jsonE) {
          print('JSON decode error: $jsonE');
        }
      }
    }
    
    return null;
  }
  
  // 删除文件
  Future<void> deleteFile(String fileId) async {
    if (!isLoggedIn) throw Exception('未登录');
    
    final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
    final params = {
      'method': 'deleteFile',
      'fileId': fileId,
      'timestamp': timestamp,
      'sessionKey': _currentUser!.sessionKey!,
    };
    
    final signature = _generateSignature('POST', '/api/open/file/deleteFile.action', params, _currentUser!.sessionSecret!);
    params['signature'] = signature;
    
    final response = await _dio.post(
      '$_apiUrl/api/open/file/deleteFile.action',
      data: params,
    );
    
    if (response.statusCode != 200 || response.data['code'] != 0) {
      throw Exception('删除文件失败: ${response.data['message']}');
    }
  }
  
  // 重命名文件
  Future<void> renameFile(String fileId, String newName) async {
    if (!isLoggedIn) throw Exception('未登录');
    
    final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
    final params = {
      'method': 'renameFile',
      'fileId': fileId,
      'fileName': newName,
      'timestamp': timestamp,
      'sessionKey': _currentUser!.sessionKey!,
    };
    
    final signature = _generateSignature('POST', '/api/open/file/renameFile.action', params, _currentUser!.sessionSecret!);
    params['signature'] = signature;
    
    final response = await _dio.post(
      '$_apiUrl/api/open/file/renameFile.action',
      data: params,
    );
    
    if (response.statusCode != 200 || response.data['code'] != 0) {
      throw Exception('重命名文件失败: ${response.data['message']}');
    }
  }
  
  // 移动文件
  Future<void> moveFile(String fileId, String targetFolderId) async {
    if (!isLoggedIn) throw Exception('未登录');
    
    final timestamp = DateTime.now().millisecondsSinceEpoch.toString();
    final params = {
      'method': 'moveFile',
      'fileId': fileId,
      'targetFolderId': targetFolderId,
      'timestamp': timestamp,
      'sessionKey': _currentUser!.sessionKey!,
    };
    
    final signature = _generateSignature('POST', '/api/open/file/moveFile.action', params, _currentUser!.sessionSecret!);
    params['signature'] = signature;
    
    final response = await _dio.post(
      '$_apiUrl/api/open/file/moveFile.action',
      data: params,
    );
    
    if (response.statusCode != 200 || response.data['code'] != 0) {
      throw Exception('移动文件失败: ${response.data['message']}');
    }
  }
  
  // 计算文件MD5
  static Future<String> calculateFileMd5(File file) async {
    final bytes = await file.readAsBytes();
    final digest = md5.convert(bytes);
    return digest.toString();
  }
}